import java.util.ArrayList;
import java.util.Collections;

public class GenericGraph {

	private ArrayList<Vertex> genericGraph = new ArrayList<Vertex>();
	private ArrayList<Vertex> topologicSorted = new ArrayList<Vertex>();
	private ArrayList<Vertex> topologicReversed = new ArrayList<Vertex>();

	public void addVertex(String from, String to, double cost) {
		Vertex vertexTo = getVertex(to);
		Vertex vertexFrom = getVertex(from);
		if (vertexFrom == null) {
			vertexFrom = new Vertex(from);
			genericGraph.add(vertexFrom);
		}
		if (vertexTo == null) {
			vertexTo = new Vertex(to);
			genericGraph.add(vertexTo);
		}
		vertexFrom.addEdge(vertexTo, cost);
	}

	private Vertex getVertex(String vertexName) {
		for (Vertex vertex : genericGraph) {
			if (vertex.getName().equals(vertexName)) {
				return vertex;
			}
		}
		return null;
	}

	private boolean hasDestination(Vertex vertex, ArrayList<Vertex> list) {
		for (Vertex v : list) {
			if (v.hasDestination(vertex)) {
				return true;
			}
		}
		return false;
	}

	public void topologicSort() {
		ArrayList<Vertex> temp = genericGraph;
		while (!temp.isEmpty()) {
			Vertex vertex = null;
			for (Vertex v : temp) {
				if (!hasDestination(v, temp)) {
					vertex = v;
					break;
				}
			}
			topologicSorted.add(vertex);
			temp.remove(vertex);
		}
	}

	public void reverseList() {
		topologicReversed = (ArrayList<Vertex>) topologicSorted.clone();
		Collections.reverse(topologicReversed);
	}

	public void calculatePaths() {
		topologicSort();
		for (Vertex vertex : topologicSorted) {
			vertex.setEdgesLeastCost();
		}
		reverseList();
		for (Vertex vertex : topologicReversed) {
			vertex.setEdgesMostCost();
		}
	}

	public void printPath() {
		System.out.print(getPath());
	}

	public String getPath() {
		String temp = "";
		for (Vertex vertex : topologicSorted) {
			temp += vertex.toString() + "\n";
		}
		return temp;
	}

	public ArrayList<String> getStringedPath() {
		ArrayList<String> temp = new ArrayList<String>();
		for (Vertex vertex : topologicSorted) {
			temp.add(vertex.toString() + "\n");
		}
		return temp;
	}
}
